package ldh.database;

import ldh.database.util.JdbcType;
import ldh.maker.util.FreeMakerUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Table {

	private Integer id;
	//列
	private List<Column> columnList;
	//表名
	private String name;
	//主键
	private PrimaryKey primaryKey;
	//外键
	private Set<ForeignKey> foreignKeys;
	//对应多的一方
	private Set<ForeignKey> many; 
	//索引
	private Set<UniqueIndex> indexies;
	//表注解
	private String comment;
	private String javaName;
	private String text;  // 文本内容
	private String sequenceName;
	private String alias; // 别名
	private String aliasQueryPrefix;
	private String aliasColumnPrefix;
	private boolean isCreate = true;
	private boolean isMiddle = false; //是否是多对多中的中间表
	
	private Set<ManyToMany> manyToManys; //多对多
	//去掉很长的列
	private List<Column> noBigableColumn = new ArrayList<Column>();

	public Table(String tableName) {
		this.name = tableName;
		initJavaName();
	}
	
	public Table(String tableName, List<Column> columnList, PrimaryKey primaryKey) {
		this(tableName);
		this.columnList = columnList;
		this.primaryKey = primaryKey;
	}
	
	public Table(String tableName, List<Column> columnList, PrimaryKey primaryKey, Set<ForeignKey> foreignColumns) {
		this(tableName, columnList, primaryKey);
		this.foreignKeys = foreignColumns;
		if (foreignKeys != null) {
			for (ForeignKey foreignKey : foreignKeys) {
				foreignKey.setTable(this);
			}
		}
		if (primaryKey != null) {
			List<Column> r = new ArrayList<>();
			for (Column c : primaryKey.getColumns()) {
				for (Column cc : columnList) {
					if (c.getName().equals(cc.getName())) {
						r.add(cc);
					}
				}
			}
			this.columnList.removeAll(r);
			this.columnList.addAll(0, primaryKey.getColumns());
		}
	}
	
	public Table(String tableName, List<Column> columnList, PrimaryKey primaryKey, Set<ForeignKey> foreighColumns, Set<UniqueIndex> indexies) {
		this(tableName, columnList, primaryKey, foreighColumns);
		this.indexies = indexies;
	}
	
	public List<Column> getColumnList() {
		return columnList;
	}

	public String getName() {
		return name;
	}

	public PrimaryKey getPrimaryKey() {
		return primaryKey;
	}

	public Set<UniqueIndex> getIndexies() {
		if (indexies == null) {
			indexies = new HashSet<>();
		}
		return indexies;
	}

	public void setIndexies(Set<UniqueIndex> indexies) {
		this.indexies = indexies;
	}

	public void setColumnList(List<Column> columnList) {
		this.columnList = columnList;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<ForeignKey> getForeignKeys() {
		if (foreignKeys == null) {
			foreignKeys = new HashSet<>();
		}
		return foreignKeys;
	}

	public void setForeignKeys(Set<ForeignKey> foreignKeys) {
		this.foreignKeys = foreignKeys;
	}

	public String getComment() {
		if (comment == null || comment.equals("") || comment.equals(name)) {
			return null;
		}
			
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
		if (text == null) text = comment;
	}

	public String getJavaName() {
		return javaName;
	}

	public void setJavaName(String javaName) {
		this.javaName = javaName;
	}
	
	private void initJavaName() {
		javaName = FreeMakerUtil.firstUpper(FreeMakerUtil.javaName(name));
	}
	
	public Set<ForeignKey> getMany() {
		if (many == null) {
			many = new HashSet<ForeignKey>();
		}
		Set<ForeignKey> remove = new HashSet<>();
		for(ForeignKey fk : many) {
			if (fk.getTable().isMiddle()) {
				remove.add(fk);
			}
		}
		many.removeAll(remove);
		return many;
	}
	
	public void addMany(ForeignKey foreignKey) {
		Table table = foreignKey.getTable();
		boolean isAdd = false;
		for (ForeignKey fk : getMany()) {
			if (table == fk.getTable()) {
				isAdd = true;
			}
			if (foreignKey.getTable().getName().equals(fk.getTable().getName())) {
				isAdd = true;
			}
		}
		if (!isAdd && !foreignKey.getTable().isMiddle()) {
			getMany().add(foreignKey);
		}
	}

	public String getSequenceName() {
		return sequenceName;
	}

	public void setSequenceName(String sequenceName) {
		this.sequenceName = sequenceName;
	}

	public List<Column> getNoBigableColumn() {
		if(noBigableColumn.size() < 1 && columnList != null) {
			for (Column c : columnList) {
				JdbcType jdbcType = JdbcType.valueOf(c.getType());
				if (jdbcType != JdbcType.BLOB && jdbcType != JdbcType.CLOB && c.getSize() < 1000) {
					noBigableColumn.add(c);
				}
			}
		}
		return noBigableColumn;
	}

	public boolean isCreate() {
		return isCreate;
	}

	public void setCreate(boolean isCreate) {
		this.isCreate = isCreate;
	}

	public boolean isMiddle() {
		return isMiddle;
	}

	public String getAlias() {
		return alias;
	}

	public String getAliasQueryPrefix() {
		return aliasQueryPrefix;
	}

	public String getAliasColumnPrefix() {
		return aliasColumnPrefix;
	}

	public void setAlias(String alias) {
		this.alias = alias;
		if (alias != null && alias.equals("")) {
			aliasColumnPrefix = "";
			aliasQueryPrefix = "";
		} else {
			aliasColumnPrefix = alias + ".";
			aliasQueryPrefix = alias + "_";
		}
	}

	public void setMiddle(boolean isMiddle) {
		this.isMiddle = isMiddle;
	}

	public Set<ManyToMany> getManyToManys() {
		if (manyToManys == null) {
			manyToManys = new HashSet<>();
		}
		return manyToManys;
	}
	
	public void addManyToMany(ManyToMany manyToMany) {
		if (manyToManys == null) {
			manyToManys = new HashSet<ManyToMany>();
		}
		boolean ishave = false;
		for (ManyToMany mtm : manyToManys) {
			if (mtm.equals(manyToMany)) {
				ishave = true;
			}
		}
		if (!ishave) {
			manyToManys.add(manyToMany);
		}
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
}
